package core;

import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import superweapons.SuperWeapon;

import towers.Tower;

public class Mouse extends MouseAdapter implements MouseMotionListener {
	
	private Unit selectedItem;
	private Model model;
	private Point mouseDot = new Point();
	private Point laatstePunt;
	private Point vorigeLaatstePunt;
	
	private Controller controller;
	
	public Mouse( Model model, Controller c ){
		this.model = model;
		this.controller = c;
	}
	
	private boolean clickedInField( Point p  ){
		return ( p.x < Model.battlefieldWidth && p.y < Model.battlefieldHeight );
	}
	
	/**
	 * Gaat mousepoint doorgeven aan een model class
	 */
	public void mouseClicked( MouseEvent e ){
		Point p = e.getPoint();
		
		if( model.isMapEditor() )
		{
			if ( controller.getMapeditorType().equals("base") )
			{
				model.placeBase( new Point(p.x - Base.baseWidth / 2, p.y - Base.baseHeight / 2) );
			}
			else if( controller.getMapeditorType().equals("road") )
			{
				if ( laatstePunt != null )
				{
					boolean correct = false;
					if ( p.x == laatstePunt.x )
						correct = true;
					else if (Math.abs(p.x - laatstePunt.x) < 25 )
					{
						p.x = laatstePunt.x;
						correct = true;
					}
					
					if ( p.y == laatstePunt.y )
						correct = true;
					else if (Math.abs(p.y - laatstePunt.y) < 25 )
					{
						p.y = laatstePunt.y;
						correct = true;
					}
					
					if ( !(p.x == laatstePunt.x && p.y == laatstePunt.y) && correct )
					{
						vorigeLaatstePunt = laatstePunt;
						
						if ( model.addPointToRoute(new Point(p.x - Map.wayWidth / 2, p.y - Map.wayWidth / 2)))
							laatstePunt = null;
						else
							laatstePunt = p;
					}
				}
				else
				{
					vorigeLaatstePunt = laatstePunt;
					
					if ( model.addPointToRoute(new Point(p.x - Map.wayWidth / 2, p.y - Map.wayWidth / 2)))
						laatstePunt = null;
					else
						laatstePunt = p;
				}
			}
		}
		else
		{
			if (e.getButton() == MouseEvent.BUTTON1) {
				/**
				 *  moet naar (een)  model
				 */
				//als er in het veld geklikt is
				if( clickedInField( p ) ){
					//als er voorheen een tower geselecteerd is
					if( this.selectedItem != null ){
						
						//als er een tower geselecteerd is
						if(selectedItem instanceof Tower){
						
							//als de vorige toren op het veld staat
							if( this.selectedItem.position != null ){
								//als waar je nu op klikt een toren is
								if( model.getTowerByPoint( p ) != null ){
									//de toren waar op geklikt is 
									this.selectedItem = model.getTowerByPoint( p );
									//notify mijn obeservers maar eens lekker goed
									this.model.notifyObservers( "new tower selected" );
									model.repaint();
								} else {
									//null want je klikte nergens op
									this.selectedItem = null;
									model.repaint();
									
								}
							}
							//de toren wie voorheen geselecteerd is heeft geen punten
							//dit staat dus voor een nieuw te bouwen toren
							else {
								if( !model.placeOccupied( p, (Tower)selectedItem ) ){
									
									//omdat de tower in het midden moet komen als je hem ergens wilt bouwe
									p.x -= selectedItem.getSize().getWidth() / 2;
									p.y -= selectedItem.getSize().getHeight() / 2;
									
									if( model.buyTower( (Tower)selectedItem, new Point2D.Double((double)p.x, (double)p.y) ) ){
										this.selectedItem = null;
									}						
								}
								else {
									//System.out.println( "Hier bouwen is niet toegestaan" );
								}
							} // als er geen last selected item is
						
	
						}else if(selectedItem instanceof SuperWeapon){
							//selecteditem is superwapen
							model.buySuperWeapon((SuperWeapon)selectedItem, new Point2D.Double((double)p.x, (double)p.y));
							selectedItem = null;
						}
					}else{
						if( model.getTowerByPoint( p ) != null ){
							//de toren waar op geklikt is 
							this.selectedItem = model.getTowerByPoint( p );
							//notify mijn obeservers maar eens lekker goed
							this.model.notifyObservers( "new tower selected" );
							model.repaint();
						} else {
							//null want je klikte nergens op
							this.selectedItem = null;
							model.repaint();
						}
					}
				}
			}else if (e.getButton() == MouseEvent.BUTTON3) {
				selectedItem = null;
				model.repaint();
			}
		}
	}
	
	public void undoAction()
	{
		if( controller.getMapeditorType().equals("road") )
		{
			laatstePunt = vorigeLaatstePunt;
			vorigeLaatstePunt = null;
			model.verwijderLaatstePointOfRoute();
		}
	}
	
	/**
	 * @param event van mouse
	 * wanneer mouse beweegt, repainten, zodat je nice cursor krijgt.
	 */
	
	public void mouseMoved(MouseEvent e) {
	    	//controleren of er een geselecteerde toren is, die nog niet geplaatst is.
			if( selectedItem != null && selectedItem.position == null){
				//het punt van de mouse updaten en tekenen
				mouseDot = e.getPoint();
				model.repaint();
			}else{
				//zorgen dat het punt uit beeld is bij niet bestaande of reeds gebouwde toren.
				mouseDot.x = 900;
				mouseDot.y = 900;
			}
	}
	
	public void mouseDragged(MouseEvent e){
	    	
	}
	
	public Tower getSelectedItem(){
		if(selectedItem instanceof Tower)
			return (Tower)selectedItem;
		else
			return null;
	}
	
	public SuperWeapon getSelectedSuperWeapon(){
		if(selectedItem instanceof SuperWeapon)
			return (SuperWeapon)selectedItem;
		else
			return null;
	}
	
	public void setSelectedItem( Unit t ){
		this.selectedItem = t;
	}
			
	public boolean checkNewTower(){
		return ( this.selectedItem.position == null );
	}
	
	public Point getClickLocation(){
		return new Point();
	}
	
    public Point getMouseDot(){
    	return mouseDot;
    }
}
